﻿#include "OiPCH.hpp"

namespace Oi
{
    namespace PLScannerCore
    {
        class MessageOutputImpl : public Impl<MessageOutput>
        {
        public:
            void init();
            void exit();

        public:
            QTableWidget* _history;
            int breakIndex[10] = { 0 };
        };

        void MessageOutputImpl::init()
        {
            OI_Q(MessageOutput);

            QVBoxLayout* layout = new QVBoxLayout(q);
            layout->setContentsMargins(2, 2, 2, 2);
            layout->setSpacing(1);
            _history = new QTableWidget(q);
            _history->setSelectionBehavior(QAbstractItemView::SelectRows);
            _history->setSelectionMode(QAbstractItemView::SingleSelection);
            _history->setEditTriggers(QAbstractItemView::NoEditTriggers);
            _history->setContextMenuPolicy(Qt::CustomContextMenu);
            _history->setWordWrap(true);

            QStringList titleList;
            titleList << MessageOutput::tr("时间") << MessageOutput::tr("记录");
            _history->setColumnCount(titleList.size());
            _history->setHorizontalHeaderLabels(titleList);
            _history->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
            _history->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
            _history->verticalHeader()->hide();

            q->connect(_history, SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(onContextMenuRequested(const QPoint&)));

            layout->addWidget(_history);
        }

        void MessageOutputImpl::exit()
        {
        }

        MessageOutput::MessageOutput(QWidget* parent) : QWidget(parent)
        {
            OI_I(MessageOutput)->init();
        }

        MessageOutput::~MessageOutput()
        {
            OI_E(MessageOutput)->exit();
        }

        void MessageOutput::append(const QString& text, MsgStyle style)
        {
            OI_F(MessageOutput);

            check();
            switch (style)
            {
            case normal:
            {
                int index = d->breakIndex[0];

                d->_history->insertRow(index);

                QTableWidgetItem* item = new QTableWidgetItem(QDateTime::currentDateTime().toString("hh:mm"));
                d->_history->setItem(index, 0, item);

                item = new QTableWidgetItem(text);
                item->setData(Qt::UserRole + 1, normal);
                d->_history->setItem(index, 1, item);

                d->_history->resizeRowToContents(index);

                d->breakIndex[0]++;
            }

            break;
            case alarm:
            {
                int index = d->breakIndex[0] + d->breakIndex[1];

                QString dispText = text;
                int errorCode = PLScannerError::ERR_UNKOWN;
                if(text.startsWith("ERR") && text.contains(":"))
                {
                    int b = text.indexOf(":");
                    errorCode = ( text.mid(3, b - 3) ).toInt();
                    dispText = text.right(text.length() - b - 1);
                }

                bool append = true;

                if (errorCode != PLScannerError::ERR_UNKOWN)
                {
                    for(int i = d->breakIndex[0]; i < index; i++)
                    {
                        auto code = d->_history->item(i, 1)->data(Qt::UserRole + 2).toInt();
                        auto str = d->_history->item(i, 1)->text();

                        if(code == errorCode &&  str == dispText)
                        {
                            append = false;
                            break;
                        }
                    }
                }

                if (append)
                {
                    d->_history->insertRow(index);

                    QTableWidgetItem* item = new QTableWidgetItem(QDateTime::currentDateTime().toString("hh:mm"));
                    item->setBackgroundColor(Qt::darkRed);
                    item->setTextColor(Qt::white);
                    d->_history->setItem(index, 0, item);

                    item = new QTableWidgetItem(dispText);
                    item->setBackgroundColor(Qt::darkRed);
                    item->setTextColor(Qt::white);
                    item->setData(Qt::UserRole + 1, alarm);
                    item->setData(Qt::UserRole + 2, errorCode);
                    d->_history->setItem(index, 1, item);

                    d->_history->resizeRowToContents(index);

                    d->breakIndex[1]++;
                }
            }
            break;
            }
            
            flush();

            if (d->breakIndex[1] > 0)
            {
                emit alarmChanged(true);
            }
        }

        void MessageOutput::check()
        {
             OI_F(MessageOutput);

             if (d->breakIndex[0] > 30)
             {
                 d->_history->removeRow(0);
                 d->breakIndex[0]--;
             }
        }

        void MessageOutput::flush()
        {
            OI_IMPL()->_history->verticalScrollBar()->setValue(OI_IMPL()->_history->verticalScrollBar()->maximum());
        }

        void MessageOutput::clear()
        {
            OI_IMPL()->_history->clearContents();
            OI_IMPL()->_history->setRowCount(0);

            memset(OI_IMPL()->breakIndex, 0, sizeof(int) * 10);
        }

        void MessageOutput::clear(const QString& text)
        {
            OI_F(MessageOutput);

            int errorCode = -1;

            if(text.startsWith("ERR"))
            {
                errorCode = text.mid(3).toInt();
            }

            if (errorCode >= 0)
            {
                for(int i = d->breakIndex[0]; i < d->breakIndex[0] + d->breakIndex[1]; i++)
                {
                    auto code = d->_history->item(i, 1)->data(Qt::UserRole + 2).toInt();

                    if(code == errorCode)
                    {
                        d->_history->removeRow(i);
                        d->breakIndex[1] --;
                        i--;
                    }
                }
            }

            if(d->breakIndex[1] == 0)
            {
                emit alarmChanged(false);
            }
        }

        void MessageOutput::onContextMenuRequested(const QPoint& pos)
        {
            OI_F(MessageOutput);
            QMenu menu;
            auto clearAllAction = menu.addAction("清除全部记录");
            auto ret = menu.exec(d->_history->mapToGlobal(pos));

            if(clearAllAction == ret)
            {
                clear();
            }
        }

       

    }
}
